﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LjServer
{

    //生成更新数据项
    
    class invalidationData
    {
        static Random r = null;
        int numDataElements;
        double[] sums;
        bool defaultSelectZipf = true;
        double a = 1.0;//(1/r^a)
        public invalidationData(int numDataElements, double e)
        {
            a = e;
            this.numDataElements = numDataElements;
            sums = new double[numDataElements];
            double sum = 0.0;


            for (int i = 0; i < sums.Length; i++)
            {

                sum += 1.0 / Math.Pow((double)(i + 2), a);
            }
            for (int i = 0; i < sums.Length; i++)
            {
                if (i == 0)
                    sums[i] = 1.0 / Math.Pow((double)(i + 2), a) / sum;
                else
                    sums[i] = sums[i - 1] + 1.0 / Math.Pow((double)(i + 2), a) / sum;
            }
        }
        public static void SetRandomSeed(int seed)
        {
            r = new Random(seed + 13);
        }

        public void SetDefaultToUniform()
        {
            this.defaultSelectZipf = false;
        }

        public int Pick()
        {
            return Pick(this.defaultSelectZipf);
        }
  
        public int Pick(bool zipfSelect)
        {
            int indx;
            if (zipfSelect)
            {
                double u = r.NextDouble();
                indx = 0;
                while (u > sums[indx]) indx++;
            }
            else
            {
                indx = r.Next(this.numDataElements);
            }
            return indx;
        }

       
        int iset;
        double gset;
        Random r1, r2;

        public invalidationData()
        {
            r1 = new Random(unchecked((int)DateTime.Now.Ticks));
            r2 = new Random(~unchecked((int)DateTime.Now.Ticks));
            iset = 0;
        }

        public double Next()
        {
            double fac, rsq, v1, v2;
            if (iset == 0)
            {
                do
                {
                    v1 = 2.0 * r1.NextDouble() - 1.0;
                    v2 = 2.0 * r2.NextDouble() - 1.0;
                    rsq = v1 * v1 + v2 * v2;
                } while (rsq >= 1.0 || rsq == 0.0);

                fac = Math.Sqrt(-2.0 * Math.Log(rsq) / rsq);
                gset = v1 * fac;
                iset = 1;
                return v2 * fac;
            }
            else
            {
                iset = 0;
                return gset;
            }

        }
    }
}
